package com.ccys.cms.service.discount.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ccys.cms.service.discount.PromoCodeAutomatedMemberService;
import com.ccys.cms.service.discount.PromoCodeAutomatedService;
import com.ccys.common.third.mailGun.MailgunUtil;
import com.ccys.common.util.HtmlUtils;
import com.ccys.common.util.Kit;
import com.ccys.common.vo.ResponseResult;
import com.ccys.db.cache.SysCodeUtil;
import com.ccys.db.dto.discount.MatchingPremiumCouponsDto;
import com.ccys.db.dto.discount.PromoCodeAutomatedDto;
import com.ccys.db.entity.SysCode;
import com.ccys.db.entity.TblPromoCodeAutomated;
import com.ccys.db.entity.TblPromoCodeAutomatedMember;
import com.ccys.db.mapper.TblMemberMapper;
import com.ccys.db.mapper.TblPromoCodeAutomatedMapper;
import com.ccys.db.mapper.TblPromoCodeAutomatedMemberMapper;
import com.ccys.db.page.PageDto;
import com.ccys.db.rely.service.impl.BaseServiceImpl;
import com.ccys.db.service.BaseTblAuditTrailWebService;
import com.ccys.db.vo.discount.PromoCodeAutomatedMemberListVo;
import com.ccys.db.vo.discount.PromoCodeAutomatedPageQueryVo;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: WhiteCoat
 * @description: 自动优惠卷接口实现类
 * @author: ZhangJingCan
 * @create: 2023-12-15 15:35
 **/

@Service
@Slf4j
public class PromoCodeAutomatedServiceImpl extends BaseServiceImpl<TblPromoCodeAutomated> implements PromoCodeAutomatedService {

    @Resource
    private TblPromoCodeAutomatedMapper tblPromoCodeAutomatedMapper;

    /**
     * 副表 - 用于存储自动生成的优惠卷匹配的人的集合数据
     */
    @Resource
    private TblPromoCodeAutomatedMemberMapper tblPromoCodeAutomatedMemberMapper;

    @Autowired(required = false)
    private PromoCodeAutomatedMemberService promoCodeAutomatedMemberService;

    /**
     * 病人表
     */
    @Resource
    private TblMemberMapper tblMemberMapper;

    /**
     * 用于保存修改状态日志
     */
    @Autowired(required = false)
    private BaseTblAuditTrailWebService baseTblAuditTrailWebService;

    // 创建一个ExecutorService用于执行异步任务。
    private final ExecutorService executorService = Executors.newSingleThreadExecutor();


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult savePromoCodeAutomated(PromoCodeAutomatedDto dto) {
        //基础校验
        Kit.allParamValid(dto, "name", "generateType", "type", "emailMatchingPattern", "status", "sendEmail", "receiver");
        //判断GenerateType不等于2的时候需要校验
        if (!dto.getGenerateType().equals(2)) {
            Kit.allParamValid(dto, "prefix", "generateLength", "limitNumber", "endType", "reusable");
        }
        if (dto.getType() != 0) {
            if (ObjectUtil.isEmpty(dto.getAmount())) {
                return ResponseResult.error("Parameter error, please enter Amount!");
            }
        }
        if (dto.getEndType().equals(0)) {
            if (ObjectUtil.isEmpty(dto.getEndDuration())) {
                return ResponseResult.error("Parameter error, please enter the duration (in days)");
            }
        } else if (dto.getEndType().equals(1)) {
            if (ObjectUtil.isEmpty(dto.getEndDate())) {
                return ResponseResult.error("Parameter error, please select expiration time");
            }
        } else {
            return ResponseResult.error("parameter error!");
        }
        //校验字符串是否符合格式，格式只能为:%xx或者xx%或者%xx%或者xx
        boolean b = validateEmailMatchingPattern(dto.getEmailMatchingPattern());
        if (!b) {
            return ResponseResult.error("Please enter the correct email matching pattern format, which should be:% xx or xx% or% xx% or xx.% is not allowed in the middle of the entered email matching pattern！");
        }
        //拼接字符串 - 这里面会校验如果没有%  会在两边拼接上% 如果左边或者右边或者两边都有%则不会操作，直接返回
        dto.setEmailMatchingPattern(processInputForFuzzySearch(dto.getEmailMatchingPattern()));
        //0auto 1NRIC 2pre existing promo code 0-自动，1-身份证，2-选择的普通优惠卷的code
        //这里只需要判断=0 - 自动去拼接优惠卷名称 - 其余的，1-身份证的，发送邮件的时候再根据当前用户的身份证来拼接,2-直接放在code字段的，不需要再操作
        if (0 == dto.getGenerateType()) {
            //设置code = 传入的前缀 + 传入的自动生成长度得到的随机字符串
            dto.setCode(dto.getPrefix() + Kit.getStrByLength(dto.getGenerateLength()));
        }
        //添加/修改
        return ResponseResult.update(this.insertOrUpdate(dto));
    }

    /**
     * 根据传入的用户信息去查询匹配高级优惠卷
     *
     * @param dto 用户信息：id - 身份证 - 邮箱号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void queryAvailablePremiumCouponsByEmail(MatchingPremiumCouponsDto dto) throws ParseException {
        Kit.allParamValid(dto, "id", "email", "nricFin", "fullName", "countryId", "currency");
        //查询当前传入的用户能匹配到的高级优惠卷集合 - 这里查询也会连表副表，检查这个用户如果已经有了这个优惠卷，就不会再次查询出来了。
        //比如本次匹配到三个优惠卷 - 本次发送时会存入副表，下次如果用户修改了邮箱，然后再次来到这里
        //会检查副表，对比-这三个优惠卷不会再次发送 - 只会发送这三个优惠卷之外的，以此类推。
        List<TblPromoCodeAutomated> automatedList = tblPromoCodeAutomatedMapper.findListByEmail(dto.getEmail(), dto.getId());
        //不为空才继续
        if (ObjectUtil.isNotEmpty(automatedList)) {
            //装入副表对象的集合
            List<TblPromoCodeAutomatedMember> memberList = new ArrayList<>();
            //直接循环高级优惠卷集合
            for (TblPromoCodeAutomated automated : automatedList) {
                //每次循环检查当前高级优惠卷的GenerateType - 如果为1 - 代表身份证 - 需要拿着用户的身份证以及GenerateLength长度 - 生成code
                //注意 - 这个类型的code是没值的，需要现在生成
                if (1 == automated.getGenerateType()) {
                    //生成规则：前缀 + 获取用户身份证后n位
                    automated.setCode(automated.getPrefix() + Kit.truncateStringByLength(dto.getNricFin(), automated.getGenerateLength()));
                }

                //创建副表对象
                TblPromoCodeAutomatedMember member = new TblPromoCodeAutomatedMember();
                //设置公共的字段值
                member.setPromoCodeId(automated.getId());
                member.setMemberId(dto.getId());
                //使用限制 0 为无限
                member.setCodeUsedNumber(automated.getLimitNumber());
                //不同的类型组成code的方式不一样
                if (0 == automated.getGenerateType()) {
                    //自动生成的方式
                    member.setCode(automated.getPrefix() + Kit.getStrByLength(automated.getGenerateLength()));
                } else if (1 == automated.getGenerateType()) {
                    member.setCode(automated.getPrefix() + Kit.truncateStringByLength(dto.getNricFin(), automated.getGenerateLength()));
                } else if (2 == automated.getGenerateType()) {
                    member.setCode(automated.getCode());
                } else {
                    log.error("用户匹配高级优惠卷时数据发现GenerateType错误,错误的优惠卷数据ID为：{}", automated.getId());
                    //开始下一次循环 - 这条数据就不添加了
                    continue;
                }
                member.preInsert();
                //判断当前优惠卷属于什么类型 - 0-持续时长(天),1-到期时间 - 注意，上面的sql查询已经过滤了类型为1到期时间的数据，这里不会出现早于当前时间的数据
                if (0 == automated.getEndType()) {
                    //持续时长(天) - 需要将当前时间加上这个天数的时间再设置进副表的到期时间字段
                    //设置结束时间 - 当前时间加上传入的天数 - 得到未来某个时间
                    member.setEndDate(Kit.addDays(automated.getEndDuration()));
                } else if (1 == automated.getEndType()) {
                    //到期时间 - 到期时间直接往副表装入即可
                    member.setEndDate(automated.getEndDate());
                } else {
                    log.error("用户匹配高级优惠卷时数据发现EndType错误,错误的优惠卷数据ID为：{}", automated.getId());
                    //开始下一次循环 - 这条数据就不添加了
                    continue;
                }
                //加入集合 - 用于批量新增数据
                memberList.add(member);
            }
            //批量新增副表数据
            promoCodeAutomatedMemberService.insertAll(memberList);

            //发送邮件
            sendEmailPromotionCode(dto, automatedList, 0, null);
        }
    }


    /**
     * 组装高级优惠卷的邮件数据
     *
     * @param dto            用户参数
     * @param codes          高级优惠卷数据集合
     * @param type           类型
     * @param depentFullName 不知道干嘛的
     */
    public static void sendEmailPromotionCode(MatchingPremiumCouponsDto dto, List<TblPromoCodeAutomated> codes, int type, String depentFullName) {
        try {
            // 读取邮件模板
            String templateContent = HtmlUtils.getTemplateContent("PromotionCodeEmail.ftl", null);

            String name = "";
            if (type == 0) {
                name = "your";
            } else {
                name = dto.getFullName() + "'s";
            }

            //货币符号
            String currency = dto.getCurrency();

            //替换内容
            templateContent = templateContent.replace("[Open_URL]", "getAppURL().trim()" + "/v1/open-whitecoat");

            if (codes.size() <= 0) {
                //替换方法 -> 会将字符串中所有的Benefits替换为-
                templateContent = templateContent.replace("Benefits", "-");
            } else {
                //拼接内容
                StringBuilder benefitStringBuilder = new StringBuilder();

                //获取上班时间
                SysCode standardFee = SysCodeUtil.getCode("Standard_Fee","2");
                BigDecimal priceOfficeHour;
                if (ObjectUtil.isNotEmpty(standardFee) && ObjectUtil.isNotEmpty(standardFee.getValue())) {
                    try {
                        //获取值 - 并且转换为BigDecimal 如果转换失败则设置为0
                        priceOfficeHour = new BigDecimal(standardFee.getValue());
                    } catch (NullPointerException | NumberFormatException e) {
                        priceOfficeHour = BigDecimal.ZERO;
                    }
                } else {
                    //如果为null - 也直接设置为0
                    priceOfficeHour = BigDecimal.ZERO;
                }


                //获取下班时间的金额 - PRICE_AFTER_OFFICE_HOUR
                SysCode surchargeFee = SysCodeUtil.getCode("Surcharge_Fee","2");
                BigDecimal priceAfterOfficeHour;
                if (ObjectUtil.isNotEmpty(surchargeFee) && ObjectUtil.isNotEmpty(surchargeFee.getValue())) {
                    try {
                        //获取值 - 并且转换为BigDecimal 如果转换失败则设置为0
                        priceAfterOfficeHour = new BigDecimal(surchargeFee.getValue());
                    } catch (NullPointerException | NumberFormatException e) {
                        priceAfterOfficeHour = BigDecimal.ZERO;
                    }
                } else {
                    //如果为null - 也直接设置为0
                    priceAfterOfficeHour = BigDecimal.ZERO;
                }

                for (int i = 0; i < codes.size(); i++) {
                    TblPromoCodeAutomated item = codes.get(i);
                    if (i != 0) {
                        benefitStringBuilder.append("<h3 style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>OR</strong></h3>");
                        benefitStringBuilder.append("<div class='o_hide-xs' style='font-size: 20px; line-height: 20px; height: 20px; '>&nbsp;</div>");
                    }
                    benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>In line with " + name + " corporate healthcare benefits, you are entitled to</strong></p>");
                    benefitStringBuilder.append("<div class='o_hide-xs' style='font-size: 20px; line-height: 20px; height: 20px; '>&nbsp;</div>");

                    String sBenefit = "";
                    //检查金额 - 如果为空设置为0
                    BigDecimal amount;
                    //判断不为空 - 为空则设置为0
                    if (ObjectUtil.isNotEmpty(item.getAmount())) {
                        amount = item.getAmount();
                    } else {
                        //设置为0
                        amount = BigDecimal.ZERO;
                    }


                    //类型等于:0:free delivery(快递费用免费)
                    if (0 == item.getType()) {
                        sBenefit = currency + "0 for medication delivery (as applicable)";
                    } else if (1 == item.getType()) {
                        //1:fixed $ off bill(账单抵扣金额)
                        //用于结果的字符串 - 可能为整数可能为带有两位小数
                        String amountStr = "0";
                        //先判断amount不为null
                        if (ObjectUtil.isNotEmpty(item.getAmount())) {
                            //判断amount是否为整数
                            if (amount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                                //是整数 - 将item.getAmount()设置为整数并拼接
                                amountStr = amount.stripTrailingZeros().toPlainString();
                            } else {
                                //不是整数则保留两位小数 - 直接去除多余的小数保留两位小数
                                amountStr = amount.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
                            }
                        }
                        //拼接最终字符串 - 如果未进上面的if内 那么直接使用默认值
                        sBenefit = currency + amountStr + " off your total medical bill";

                    } else if (2 == item.getType()) {
                        //2:% off bill(账单打折)
                        //用于结果的字符串 - 可能为整数可能为带有两位小数
                        String amountStr = "0";
                        //先判断amount不为null
                        if (ObjectUtil.isNotEmpty(item.getAmount())) {
                            //判断amount是否为整数
                            if (amount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                                //是整数 - 将item.getAmount()设置为整数并拼接
                                amountStr = amount.stripTrailingZeros().toPlainString();
                            } else {
                                //不是整数则保留两位小数 - 直接去除多余的小数保留两位小数
                                amountStr = amount.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
                            }
                        }
                        //拼接最终字符串 - 如果未进上面的if内 那么直接使用默认值
                        sBenefit = amountStr + "% off your total medical bill";
                    } else if (3 == item.getType()) {
                        //3:fixed $ off consultation(问诊费用抵扣金额)
                        // 创建新的 BigDecimal 对象
                        BigDecimal newValue;


                        // 使用 compareTo 方法比较 a 和 b 的值
                        // 如果 amount 大于 priceOfficeHour，compareTo 返回 1，否则返回 -1 或 0
                        if (priceOfficeHour.compareTo(amount) < 0) {
                            // 如果 b 大于 a，将新的 BigDecimal 对象设置为 0
                            newValue = BigDecimal.ZERO;
                        } else {
                            // 如果 amount 小于或等于 priceOfficeHour，计算 priceOfficeHour 减去 amount 的值
                            newValue = priceOfficeHour.subtract(amount);
                        }

                        //判断是否为整数
                        if (newValue.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            //整数
                            sBenefit = currency + newValue.stripTrailingZeros().toPlainString() + "/office hours consult";
                        } else {
                            //不是整数 - 保留两位小数 - 这里直接去除两位之后的数值
                            sBenefit = currency + newValue.setScale(2, BigDecimal.ROUND_DOWN).toPlainString() + "/office hours consult";
                        }

                        benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>[" + sBenefit + "]</strong></p>");

                        //计算下班后的价格
                        if (priceAfterOfficeHour.compareTo(amount) < 0) {
                            // 如果 b 大于 a，将新的 BigDecimal 对象设置为 0
                            newValue = BigDecimal.ZERO;
                        } else {
                            // 如果 amount 小于或等于 priceOfficeHour，计算 priceOfficeHour 减去 amount 的值
                            newValue = priceOfficeHour.subtract(amount);
                        }

                        //下班后的价格
                        if (newValue.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            //整数
                            sBenefit = currency + newValue.stripTrailingZeros().toPlainString() + "/after hours consult";
                        } else {
                            //不是整数
                            sBenefit = currency + newValue.setScale(2, BigDecimal.ROUND_DOWN).toPlainString() + "/after hours consult";
                        }

                    } else if (4 == item.getType()) {
                        //4:% off consultation(问诊费用打折)
                        //计算上班时间 - 系统参数的上班时间减去(当前优惠卷填写的金额 / 100 * 系统参数的上班时间)并且保留两位小数 - 这里直接去除多余的小数位
                        BigDecimal workingHoursAmount = priceOfficeHour.subtract((amount.divide(new BigDecimal(100)).multiply(priceOfficeHour))).setScale(2, BigDecimal.ROUND_DOWN);
                        //判断是否为整数
                        if (workingHoursAmount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            sBenefit = currency + workingHoursAmount.stripTrailingZeros().toPlainString() + "/office hours consult";
                        } else {
                            //不是整数则保留两位小数 - 这里实际上不用再次设置保留两位小数了 -
                            sBenefit = currency + workingHoursAmount.toPlainString() + "/office hours consult";
                        }
                        benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>[" + sBenefit + "]</strong></p>");

                        //计算下班之后的价格 - 系统参数的下班时间金额减去(当前优惠卷填写的金额 / 100 * 系统参数的下班时间金额)并且保留两位小数 - 这里直接去除多余的小数位
                        BigDecimal priceAfterWork = priceAfterOfficeHour.subtract((amount.divide(new BigDecimal(100)).multiply(priceAfterOfficeHour))).setScale(2, BigDecimal.ROUND_DOWN);
                        //判断是否为整数
                        if (priceAfterWork.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            sBenefit = currency + priceAfterWork.stripTrailingZeros().toPlainString() + "/after hours consult";
                        } else {
                            //不是整数则直接设置即可 - 上面已经设置了保留两位小数
                            sBenefit = currency + priceAfterWork.toPlainString() + "/after hours consult";
                        }

                    } else if (5 == item.getType()) {
                        //5:fixed $ off delivery(快递费用抵扣金额)
                        //todo：
//                        SysCode courierFeeSysCode;
//                        if (dto.getCountryId().equals("245")) {
//                            //越南 - 获取系统参数对象
//                            courierFeeSysCode = SysCodeUtil.getCode("Delivery_Fee_VN");
//                        } else if (dto.getCountryId().equals("136")) {
//                            //马来西亚
//                            courierFeeSysCode = SysCodeUtil.getCode("Delivery_Fee_MY");
//                        } else {
//                            //否则取新加坡
//                            courierFeeSysCode = SysCodeUtil.getCode("Delivery_Fee");
//                        }
//                        BigDecimal courierFee;
//                        //判断并赋值
//                        if (ObjectUtil.isNotEmpty(courierFeeSysCode) && ObjectUtil.isNotEmpty(courierFeeSysCode.getValue())) {
//                            try {
//                                //获取值 - 并且转换为BigDecimal 如果转换失败则设置为0
//                                courierFee = new BigDecimal(courierFeeSysCode.getValue());
//                            } catch (NullPointerException | NumberFormatException e) {
//                                courierFee = BigDecimal.ZERO;
//                            }
//                        } else {
//                            //如果为null - 也直接设置为0
//                            courierFee = BigDecimal.ZERO;
//                        }


                        if (amount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            //设置整数
                            sBenefit = currency + amount.stripTrailingZeros().toPlainString() + " off your delivery fee";
                        } else {
                            //不是整数则去除多余的小数 - 保留两位小数 - 这里是直接去除，没有四舍五入或者向上向下取值。
                            sBenefit = currency + amount.setScale(2, BigDecimal.ROUND_DOWN).toPlainString() + " off your delivery fee";
                        }
                    } else if (6 == item.getType()) {
                        //6:% off delivery(快递费用打折)
                        if (amount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            //设置整数
                            sBenefit = amount.stripTrailingZeros().toPlainString() + "% off your delivery bill";
                        } else {
                            //不是整数则去除多余的小数 - 保留两位小数 - 这里是直接去除，没有四舍五入或者向上向下取值。
                            sBenefit = amount.setScale(2, BigDecimal.ROUND_DOWN).toPlainString() + "10% off your delivery bill";
                        }
                    } else if (7 == item.getType()) {
                        //7:%off consultation + % off delivery(问诊费用与快递费用同时打折)
                        //问诊费
                        //计算上班时间 - 系统参数的上班时间减去(当前优惠卷填写的金额 / 100 * 系统参数的上班时间)并且保留两位小数 - 这里直接去除多余的小数位
                        BigDecimal workingHoursAmount = priceOfficeHour.subtract((amount.divide(new BigDecimal(100)).multiply(priceOfficeHour))).setScale(2, BigDecimal.ROUND_DOWN);
                        //判断是否为整数
                        if (workingHoursAmount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            sBenefit = currency + workingHoursAmount.stripTrailingZeros().toPlainString() + "/office hours consult";
                        } else {
                            //不是整数则保留两位小数 - 这里实际上不用再次设置保留两位小数了 -
                            sBenefit = currency + workingHoursAmount.toPlainString() + "/office hours consult";
                        }
                        benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>[" + sBenefit + "]</strong></p>");

                        //计算下班之后的价格 - 系统参数的下班时间金额减去(当前优惠卷填写的金额 / 100 * 系统参数的下班时间金额)并且保留两位小数 - 这里直接去除多余的小数位
                        BigDecimal priceAfterWork = priceAfterOfficeHour.subtract((amount.divide(new BigDecimal(100)).multiply(priceAfterOfficeHour))).setScale(2, BigDecimal.ROUND_DOWN);
                        //判断是否为整数
                        if (priceAfterWork.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            sBenefit = currency + priceAfterWork.stripTrailingZeros().toPlainString() + "/after hours consult";
                        } else {
                            //不是整数则直接设置即可 - 上面已经设置了保留两位小数
                            sBenefit = currency + priceAfterWork.toPlainString() + "/after hours consult";
                        }
                        //下班之后的价格设置进
                        benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>[" + sBenefit + "]</strong></p>");

                        //快递费用打折
                        if (amount.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)) {
                            //设置整数
                            sBenefit = amount.stripTrailingZeros().toPlainString() + "% off your delivery bill";
                        } else {
                            //不是整数则去除多余的小数 - 保留两位小数 - 这里是直接去除，没有四舍五入或者向上向下取值。
                            sBenefit = amount.setScale(2, BigDecimal.ROUND_DOWN).toPlainString() + "10% off your delivery bill";
                        }

                    }

                    benefitStringBuilder.append("<p style='margin-top: 0px; margin-bottom: 0px; color: #333;'><strong>[" + sBenefit + "]</strong></p>");
                    benefitStringBuilder.append("<div class='o_hide-xs' style='font-size: 20px; line-height: 20px; height: 20px;'>&nbsp;</div>");
                    benefitStringBuilder.append("<p class='o_text-dark' style='width: 70%; color: #242b3d;margin-top: 0px;margin-bottom: 0px;font-family: Helvetica, Arial, sans-serif;margin-top: 0px;margin-bottom: 0px;font-size: 19px;line-height: 28px;background-color: #ebf5fa;border-radius: 4px;padding-left: 8px;padding-right: 8px;padding-top: 24px;padding-bottom: 24px;'><strong>" + item.getCode() + "</strong></p>");
                    benefitStringBuilder.append("<div class='o_hide-xs' style='font-size: 20px; line-height: 20px; height: 20px; '>&nbsp;</div>");
                }

                templateContent = templateContent.replace("[Benefits]", benefitStringBuilder.toString());
            }
            //调用方法发送邮件
            MailgunUtil.sendEmail(dto.getEmail(), "Here's How You can Apply Your WhiteCoat Corporate Healthcare Benefit", null, templateContent);
        } catch (Exception e) {
            log.error("匹配高级优惠卷发送邮件时，获取邮件模版失败！");
            throw new RuntimeException(e);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deletePromoCodeAutomated(PromoCodeAutomatedDto dto) {
        //判断
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter Error!");
        }
        //需要查询副表 tbl_promo_code_automated_member 是否存在关联并且未删除的数据 - 存在：返回错误信息
        Example example = new Example(TblPromoCodeAutomatedMember.class);
        example.createCriteria().andEqualTo("promoCodeId", dto.getId()).andEqualTo("delFlag", 0);
        if (tblPromoCodeAutomatedMemberMapper.selectCountByExample(example) > 0) {
            return ResponseResult.error("The current premium coupon still has associated user data that has not been deleted, so deletion is prohibited!");
        }

        //准备实体类并赋值
        TblPromoCodeAutomated automated = new TblPromoCodeAutomated();
        automated.setId(dto.getId());
        automated.setDelFlag(1);
        //判断是否修改成功 - 返回不同状态
        if (tblPromoCodeAutomatedMapper.updateByPrimaryKeySelective(automated) > 0) {
            return ResponseResult.success("Delete Successful!");
        }
        return ResponseResult.error("Delete Failed!");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updatePromoCodeAutomatedStatus(PromoCodeAutomatedDto dto) {
        //校验
        if (ObjectUtil.isEmpty(dto.getId()) || ObjectUtil.isEmpty(dto.getStatus())) {
            return ResponseResult.error("Parameter Error!");
        }
        //准备数据修改
        TblPromoCodeAutomated automated = new TblPromoCodeAutomated();
        automated.setId(dto.getId());
        automated.setStatus(dto.getStatus());
        if (tblPromoCodeAutomatedMapper.updateByPrimaryKeySelective(automated) > 0) {
            baseTblAuditTrailWebService.saveStatusLog(dto, dto.getStatus());
            return ResponseResult.success("Modified successfully!");
        }
        return ResponseResult.error("Modification failed!");
    }

    @Override
    public ResponseResult<PageInfo<PromoCodeAutomatedPageQueryVo>, Object> findPagePromoCodeAutomated(PromoCodeAutomatedDto dto) {
        dto.setStatus(Optional.ofNullable(dto.getStatus()).filter(s -> s > -1 && s < 2).orElse(null));
        dto.setType(Optional.ofNullable(dto.getType()).filter(t -> t > -1 && t < 8).orElse(null));
        //开启分页
        PageDto.startPage();
        List<PromoCodeAutomatedPageQueryVo> list = tblPromoCodeAutomatedMapper.findPagePromoCodeAutomated(dto);
        PageInfo<PromoCodeAutomatedPageQueryVo> info = new PageInfo<>(list);
        return ResponseResult.success(info);
    }

    @Override
    public ResponseResult<List<PromoCodeAutomatedMemberListVo>, Object> findListPromoCodeAutomatedMemberByCodeId(PromoCodeAutomatedDto dto) {
        //校验必传参数
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter abnormality");
        }
        List<PromoCodeAutomatedMemberListVo> list = tblPromoCodeAutomatedMemberMapper.findListPromoCodeAutomatedMemberByCodeId(dto.getId());
        return ResponseResult.success(list);
    }


    /**
     * 校验字符串是否符合特定的格式
     * 这里是校验 - 不允许字符串中间存在 % 在字符串的左右允许存在
     *
     * @param str 传入的字符串
     * @return boolean true:合格 - false - 不合格
     */
    public boolean validateEmailMatchingPattern(String str) {
        // 检查字符串是否为空
        if (str == null || str.isEmpty()) {
            throw new IllegalArgumentException("输入的字符串不能为空");
        }

        // 检查字符串是否在开始或结束处包含 '%'
        boolean startsWithPercent = str.startsWith("%");
        boolean endsWithPercent = str.endsWith("%");

        // 去除可能的开始和结束的 '%' 后检查是否还有 '%'
        String trimmedStr = str;
        if (startsWithPercent) {
            trimmedStr = trimmedStr.substring(1);
        }
        if (endsWithPercent) {
            trimmedStr = trimmedStr.substring(0, trimmedStr.length() - 1);
        }

        // 如果处理后的字符串中还包含 '%' ，则返回false
        if (trimmedStr.contains("%")) {
            return false;
        }

        // 如果没有抛出异常，则字符串符合要求 - 返回true
        return true;
    }


    /**
     * 处理输入字符串，判断模糊匹配的类型。
     *
     * @param input 输入的字符串
     * @return 转换后的字符串
     */
    public String processInputForFuzzySearch(String input) {
        // 如果输入为空，直接返回null
        if (input == null || input.isEmpty()) {
            throw new RuntimeException("Email Matching Pattern is empty");
        }

        // 根据百分号的位置，判断模糊匹配的类型
        if (input.startsWith("%") && input.endsWith("%")) {
            // 如果两边都有%，直接返回即可
            return input;
        } else if (input.startsWith("%")) {
            // 如果只在左边有%，直接返回即可
            return input;
        } else if (input.endsWith("%")) {
            // 如果只在右边有%，直接返回即可
            return input;
        } else {
            // 如果没有%，则构造全模糊匹配
            return "%" + input + "%";
        }
    }

    public static void main(String[] args) {
        String str = "%123456%";
        String[] split = str.split("%");
        if (ObjectUtil.isEmpty(split[0])) {
            System.out.println("第一个为空");
        }
        for (int i = 0; i < split.length; i++) {
            System.out.println("第" + i + "个，值为：" + split[i]);
        }
        System.out.println(split.length);
    }

}

